package person.bangbang.im.Androidgin.UI;

import java.util.List;

import person.bangbang.im.Androidgin.AboutAndroidgin;
import person.bangbang.im.Androidgin.Androidgin;
import person.bangbang.im.Androidgin.AndroidginService;
import person.bangbang.im.Androidgin.R;
import person.bangbang.im.Androidgin.Framework.Buddies;
import person.bangbang.im.Androidgin.Framework.Buddy;
import person.bangbang.im.Androidgin.Util.Log;
import person.bangbang.im.Androidgin.Util.SystemInfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.text.Layout;
import android.text.Selection;
import android.text.Spannable;
import android.text.method.LinkMovementMethod;
import android.text.method.MovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class ContactList extends ListActivity {
	private static final String TAG = "ContactList";
	private static final Boolean LOCAL_LOG 	= true;
	
	public static int LOGIN = 1;
//	public static int RESULT_OK = 1;
//	public static int RETULT_ERROR = -1;
	
	private static final int MENU_SIGNON = Menu.FIRST + 1;
	private static final int MENU_UNREG = Menu.FIRST + 2;
	private static final int MENU_FEEDBACK = Menu.FIRST + 3;
	
	private static final int DIALOG_ABOUT = 1;

	/* simulate a double key down event */
	private static long KEY_D_DOWN_TIME = System.currentTimeMillis();
	/* threshold to fire the Debuger activity (in millisecond) */
	private static long THRESHOLD = 200;
	
	/* the buddy's name (ID??) who u are chating with */
	public static final String CHAT_BUDDY_ID = "chat_buddy_id";
	private ContactAdapter mAdapter;
	
	private AndroidginService mService;
	private Buddies mBuddies = Buddies.getInstance();

	ServiceConnection mConn = new ServiceConnection(){
		public void onServiceConnected(ComponentName comp, IBinder service) {
			mService = ((AndroidginService.LocalBinder)service).getService();
			init();
		}
		public void onServiceDisconnected(ComponentName comp) {}
	};
	private void init() {
//		getListView().setEmptyView(this.findViewById(R.id.empty));
		if (mService.getState() == AndroidginService.STATE_SIGNNED) {
			

		} else {
			
		}
	}
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		// FIXME what's the diff between contact_list and contact_list_fuck
		setContentView(R.layout.contact_list_fuck);
		
		mAdapter = new ContactAdapter(getApplicationContext(),
                R.layout.contact_item
                );
		setListAdapter(mAdapter);
		
		// fuck you 
//		findViewById(R.id.contact_empty).setVisibility(View.GONE);
		bindService(new Intent(this, AndroidginService.class), mConn, BIND_AUTO_CREATE);
	}
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();

		update();
	}

	private void update(){

		List<Buddy> list = mBuddies.getAll();
		mAdapter.clear();
		for (Buddy it : list) {
			mAdapter.add(it);
			mAdapter.notifyDataSetChanged();
		}
		
		mAdapter.notifyDataSetChanged();
	}
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		// TODO Auto-generated method stub

		if (Androidgin.LOGIN_REQUEST == requestCode) {
			if (Androidgin.LOGIN_OK == resultCode) {
				update(); // always..
			} else if (Androidgin.LOGIN_CANCEL == resultCode) {

			} else {
				Log.d(TAG, "some Error occured in login..");				
			}
		}
		
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (keyCode) {
		case KeyEvent.KEYCODE_D:
			long tick = System.currentTimeMillis();
			Log.d(TAG, "The diff of 2 D donw event: " + (tick - KEY_D_DOWN_TIME));
			if (tick < KEY_D_DOWN_TIME + (THRESHOLD)) {
				startActivity(new Intent(getApplicationContext(), Debuger.class));
			}
			
			// FIXME: when getRepeatCount() != 0?
			Log.d(TAG, "Repeatcount: " + event.getRepeatCount());
			if (false || 2 == event.getRepeatCount()) {
				startActivity(new Intent(getApplicationContext(), Debuger.class));
			}
			KEY_D_DOWN_TIME = tick;
			break;

		default:
			break;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		Intent chat = new Intent(ContactList.this, ChatActivity.class);
		String iid = mBuddies.getAll().get(position).getID();
		Log.d(TAG, "the buddy's id: " + iid);
	
		chat.putExtra(CHAT_BUDDY_ID, iid);
		// TODO how to pass a Buddy object to Chat activity???
		startActivity(chat);
	}
	

	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.contact_menu, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case (R.id.menuAddAccount): {
			Intent intent = new Intent(ContactList.this, Login.class);
			startActivityForResult(intent, Androidgin.LOGIN_REQUEST);
			
			break;
		}
		case (R.id.menuUnreg): {
			mService.stopSelf();
			finish();
			
			return true;
		}
		case (R.id.menuFeedback): {
	    	Uri mailUri = Uri.parse("mailto:bangbang.song@gmail.com");
	    	Intent mail = new Intent(Intent.ACTION_SENDTO, mailUri);
	    	
	    	String body = "\n\n\n\n----do NOT del text below this----\n";
	    	body += "CurrentVersion: " + SystemInfo.getVersion(getApplicationContext(), true) + "\n";
	    	body += "VersionName: " + SystemInfo.getVersion(getApplicationContext(), false) + "\n";

//	    	body += "Version: " + Version.getVersion() + "\n";
	    	body += SystemInfo.toStr();

	    	mail.putExtra(Intent.EXTRA_TEXT, body);
	    	mail.putExtra(Intent.EXTRA_SUBJECT, 
	    			      "Feedback about Androidgin -- a mixture of ANDROId & piDGIN");
	    	startActivity(mail);
	    	
	    	break;
		}
		case R.id.menuPref: {
			startActivity(new Intent(getApplication(), PrefActivity.class));
			
			break;
		}
		case R.id.menuAbout: {
			showDialogAbout();
			
			break;
		}
		default : {
			// go through.
		}
		}
		return super.onOptionsItemSelected(item);
	}
	private void showDialogAbout() {
//		showDialog(DIALOG_ABOUT);
		startActivity(new Intent(getApplicationContext(), AboutAndroidgin.class));
	}

	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_ABOUT: {
			AlertDialog dia = new AlertDialog.Builder(this)
						.setTitle("About Androidgin")
						.setPositiveButton("KO", null)
						.create();
			TextView content = new TextView(getApplicationContext());
			content.setText(R.string.about_androidgin);
			content.setAutoLinkMask(Linkify.ALL);
			
			// suppress set to LinkMovementMethod defaulty. 
			content.setLinksClickable(false);
			content.setMovementMethod(new MyLinkMovementMethod());
			
			LinearLayout  l = new LinearLayout(getApplicationContext());
			LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
					                                                     ViewGroup.LayoutParams.FILL_PARENT);
			lp.setMargins(20, 4, 20, 4);
			l.addView(content, lp);
			
			dia.setView(l);
			
			return dia;
		}
		
		default :
			return null;
		}
	}

	// a wrapper name is better@@@
	// proxy???
	class MyLinkMovementMethod implements MovementMethod {
		private MovementMethod mParen = null;
		private String mUrl = null;
		
		public MyLinkMovementMethod() {
			 mParen = LinkMovementMethod.getInstance();
		}
		
		public boolean onKeyDown(TextView widget, Spannable buffer, int keyCode,
				KeyEvent event) {
			// TODO Auto-generated method stub
			mUrl = buffer.toString();
			
			switch (keyCode) {
			case (KeyEvent.KEYCODE_ENTER): 
			case (KeyEvent.KEYCODE_DPAD_CENTER): {
				
//				android.util.AndroidRuntimeException: Calling startActivity() 
//			    from outside of an Activity  context requires the 
//			    FLAG_ACTIVITY_NEW_TASK flag. 
//			    Is this really what you want?
//				return action(buffer);
				
				action(mUrl);
				
				return true;
			}
			}
			return mParen.onKeyDown(widget, buffer, keyCode, event);
		}
		
		public boolean onTouchEvent(TextView widget, Spannable buffer,
				MotionEvent event) {
			// TODO Auto-generated method stub
			mUrl = buffer.toString();

			switch(event.getAction()) {
			case (MotionEvent.ACTION_UP): // fall-through
			case (MotionEvent.ACTION_DOWN): {
				int x = (int) event.getX();
				int y = (int) event.getY();
				
				x -= widget.getTotalPaddingLeft();
				y -= widget.getTotalPaddingTop();
				
				x += widget.getScrollX();
				y += widget.getScrollY();
				
				Layout l = widget.getLayout();
				int line = l.getLineForVertical(y);
				int offset = l.getOffsetForHorizontal(line, x);
				
				Log.d(TAG,"get spann");
				
				ClickableSpan[] links = buffer.getSpans(offset, offset, ClickableSpan.class);
				if (links.length != 0) {

					if (MotionEvent.ACTION_DOWN == event.getAction()) {
						Log.d(TAG,"motion down. set the selections");
						
						Selection.setSelection(buffer, 
								               buffer.getSpanStart(links[0]), 
								               buffer.getSpanEnd(links[0]));
					} else { // MotionEvent.ACTION_UP
						Log.d(TAG, "do with Spann");
						
						links[0].onClick(widget);
					}
				} else {
					Log.d(TAG, "ther is no spanns");
					Selection.removeSelection(buffer);
				}
				return true;
			}
			}
			return mParen.onTouchEvent(widget, buffer, event);
		}
		
		private boolean action(String url) {
			boolean isWeb = url.startsWith("http");
			boolean isMail = !isWeb;
			Log.d(TAG, "in action....................\nurl = " + url);
			if (isWeb) {
				doWeb(url);
				
				return true;
			} else if (isMail) {
				doMail(url);
				
				return true;
			}
			
			return false;
		}
		
		public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
			// TODO Auto-generated method stub
			return mParen.onKeyOther(view, text, event);
		}

		public boolean onKeyUp(TextView widget, Spannable buffer, int keyCode,
				KeyEvent event) {
			// TODO Auto-generated method stub
			return mParen.onKeyUp(widget, buffer, keyCode, event);
		}

		public void onTakeFocus(TextView view, Spannable text, int dir) {
			// TODO Auto-generated method stub
			mParen.onTakeFocus(view, text, dir);
		}

		public boolean onTrackballEvent(TextView widget, Spannable text,
				MotionEvent event) {
			// TODO Auto-generated method stub
			return mParen.onTrackballEvent(widget, text, event);
		}

		public boolean canSelectArbitrarily() {
			// TODO Auto-generated method stub
			return mParen.canSelectArbitrarily();
		}

		public void initialize(TextView widget, Spannable text) {
			// TODO Auto-generated method stub
			mParen.initialize(widget, text);
		}
		
		class MyClickableSpan extends URLSpan {
			public MyClickableSpan(String url) {
				super(url);
			}
			public MyClickableSpan(Parcel p) {
				super(p);
			}
			
			@Override
			public void onClick(View widget) {
				// TODO Auto-generated method stub
				String url = getURL();
				Log.d("MyClickableSpan", "clicked url: " + url);
				
				if (url.startsWith("http")) {
					doWeb(url);
					
					return;
				} else if (url.matches("[a-zA-Z_.]*@[a-zA-Z_.]*")); {
					doMail(url);
					
					return;
				}
			}
		}
	}
	private void doMail(String url) {
    	Uri mailUri = Uri.parse("mailto:bangbang.song@gmail.com");
    	Intent mail = new Intent(Intent.ACTION_SENDTO, mailUri);
    	mail.putExtra(Intent.EXTRA_SUBJECT, 
    			      "Feedback about Androidgin -- a mixture of ANDROId & piDGIN");
    	
    	startActivity(mail);
	}
	private void doWeb(String url) {
		Uri webUri = Uri.parse(url);
		Intent web = new Intent(Intent.ACTION_VIEW, webUri);
		
		startActivity(web);
	}
	
	private void say(String text) {
		Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
	}
}
